#lang scheme


(provide
 ; vector with fill-factor
 create-fvector
 fvector-length
 fvector-max-length
 fvector-ref
 ;         fvector-set-length!
 fvector-append!
 fvector-set!
 fvector-first
 fvector-last

 ; TODO: bytevector with fill-factor
 ; fbytes

 ; TODO: bitvector with fill-factor
 ; fbits
 )

(define-struct fvector (length v) #:mutable #:transparent)

(define (create-fvector max-len) ; TODO: init, TODO: fill
  (make-fvector 0 (make-vector max-len #f)))

(define (fvector-first fv)
  (vector-ref (fvector-v fv) 0))

(define (fvector-last fv)
  (let ([v (fvector-v fv)])
    (vector-ref v (- (vector-length v) 1))))

(define (fvector-set-length! fv len)
  (set-fvector-length! fv len))

(define (fvector-ref fv idx)
  (unless (< -1 idx (fvector-length fv))
    (error "fvector-ref:" fv idx))
  (vector-ref (fvector-v fv) idx))

(define (fvector-set! fv idx x)
  (unless (< -1 idx (fvector-max-length fv))
    (error "fvector-set!:" fv idx))
  ; expand
  (unless (< idx (fvector-length fv))
    (set-fvector-length! fv (+ 1 idx)))
  (vector-set! (fvector-v fv) idx x))

(define (fvector-max-length fv)
  (vector-length (fvector-v fv)))

(define (fvector-append! fv x)
    (fvector-set! fv (fvector-length fv) x))
